package main.java.seguridad;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import main.java.aplicacion.ManejadorSistema;
import main.java.aplicacion.ManejadorSistemaError;
import main.java.aplicacion.juegos.entidades.Juego;
import main.java.aplicacion.juegos.excepciones.JuegoError;
import main.java.aplicacion.juegos.interfaces.JuegoMgt;
import main.java.aplicacion.systemfactory.SystemFactory;
import main.java.aplicacion.usuarios.entidades.Cliente;
import main.java.aplicacion.usuarios.entidades.Desarrollador;
import main.java.aplicacion.usuarios.excepciones.UsuarioError;
import main.java.aplicacion.usuarios.interfaces.UsuariosMgt;
import main.java.datatypes.juegos.CompraJuegoVO;
import main.java.datatypes.usuarios.ClienteVO;
import main.java.datatypes.usuarios.LoggedVO;
import main.java.datatypes.usuarios.LoggedVO.Tipo;
import main.java.seguridad.excepciones.LogueadosError;
import main.java.seguridad.excepciones.LogueadosError.TipoError;
import main.java.seguridad.interfaces.LogueadosMgt;
import main.java.datatypes.juegos.JuegoVO;


public class LogueadosMgr implements LogueadosMgt{
	private static LogueadosMgr instance = null;
	private List<LoggedVO> logueados = new ArrayList<LoggedVO>();


	public static LogueadosMgr getInstance() {
		if (instance == null) {
			instance = new LogueadosMgr();
		}
		return instance;
	}

	public void add(String nick, Tipo tipo){
		LoggedVO l = new LoggedVO();
		l.setNick(nick);
		l.setTipo(tipo);
		if(this.logueados == null) this.logueados = new ArrayList<LoggedVO>();
		this.logueados.add(l);
	}
	
	
	public List<LoggedVO> getLogueados() {
		return logueados;
	}


	public void setLogueados(List<LoggedVO> logueados) {
		this.logueados = logueados;
	}
	
	public boolean memberLogueado(String nick)
	{
		if (this.logueados!= null)
		{
			for (LoggedVO us : this.logueados) {
				if (us.getNick().equals(nick))
					return true;
			}			
		}
		return false;
	}
	
	public Tipo getTipoLogueado(String nick) throws LogueadosError
	{
		if (this.logueados!= null)
		{
			for (LoggedVO us : this.logueados) {
				if (us.getNick().equals(nick))
					return us.getTipo();
			}			
		}
		throw new LogueadosError(TipoError.USUARIO_NO_LOGUEADO);
	}
	
	
	
	public List<String> altaJuego(String nombreJuego, double tam, double precio, String descripcion, String nick) throws LogueadosError, ManejadorSistemaError, JuegoError{
		
		if(!memberLogueado(nick)){
			throw new LogueadosError (LogueadosError.TipoError.USUARIO_NO_LOGUEADO);
		}
		else{
		 JuegoMgt mj = SystemFactory.getInstance().getJuegoMgt();
		 return mj.altaJuego(nombreJuego, tam, precio, descripcion);
		} 
	}

    
    public void seleccionarDesarrollador(String nick, String nombreJuego, String dsc, double tam , double precio,List<String> categoriasJuego) throws LogueadosError, JuegoError, UsuarioError{
		if(!memberLogueado(nick)){
			throw new LogueadosError (LogueadosError.TipoError.USUARIO_NO_LOGUEADO);
		}
		else{
		 JuegoMgt mj = SystemFactory.getInstance().getJuegoMgt();
		 mj.seleccionarDesarrollador(nick, nombreJuego, dsc, tam, precio,categoriasJuego);
		} 
    }

    
    public List<String> listarJuegosAprobadosDesarrollador(String nick) throws LogueadosError, UsuarioError{
		if(!memberLogueado(nick)){
			throw new LogueadosError (LogueadosError.TipoError.USUARIO_NO_LOGUEADO);
		}
		else{
		 return SystemFactory.getInstance().getUsuarioMgt().listarJuegosAprobadosDesarrollador(nick);
		} 
    	
    }

    public boolean existeVersionPendienteAprobada(String nombreJuego , String numero, String nick) throws LogueadosError{
		if(!memberLogueado(nick)){
			throw new LogueadosError (LogueadosError.TipoError.USUARIO_NO_LOGUEADO);
		}
		else{
		 return SystemFactory.getInstance().getJuegoMgt().existeVersionPendienteAprobada(nombreJuego, numero);
		} 
    }
    
    public List<CompraJuegoVO> comprarJuego(String nick) throws LogueadosError{
    	if(!memberLogueado(nick)){
			throw new LogueadosError (LogueadosError.TipoError.USUARIO_NO_LOGUEADO);
		}
		else{
			return SystemFactory.getInstance().getJuegoMgt().comprarJuego();
		}
    	
    }
    
    public Juego find(String juego){
    	 return SystemFactory.getInstance().getJuegoMgt().find(juego);
    }
    
    public void confirmarCompra(Date d, String cliente, String juego){
    	
    	SystemFactory.getInstance().getJuegoMgt().confirmarCompra(d, cliente, juego);
    	
    }
    
    public List<String> ListarJuegos(String nick, String cat) throws ManejadorSistemaError {
    	if (memberLogueado(nick)){
    		try {
				Tipo tipo = getTipoLogueado(nick);
				UsuariosMgt umgt = SystemFactory.getInstance().getUsuarioMgt();
				ManejadorSistema ms = ManejadorSistema.getInstance();
				if (tipo.equals(Tipo.Desarrollador)){
					if (cat.equals("Todas")){
						return umgt.listarJuegosPublicadosDesarrollador(nick);
					} 
					else {
						List<String> juegosCat = new ArrayList<String>();
						for (String s: umgt.listarJuegosPublicadosDesarrollador(nick))
						{
							if (ms.findJuego(s).getCategorias().contains(cat)){
								juegosCat.add(s);
							}
						}
						return juegosCat;
					}
				}
				else {
					return ListarJuegos(cat);
				}
			} catch (LogueadosError e) {
				//Si no esta logueado devuelve todos los juegos
				return ListarJuegos(cat);
			} catch (UsuarioError e) {
				//Si no esta logueado devuelve todos los juegos
				return ListarJuegos(cat);
			}
    	}
		return ListarJuegos(cat);

    }
    
    public List<String> ListarJuegos(String cat) throws ManejadorSistemaError {
    	JuegoMgt jmgt = SystemFactory.getInstance().getJuegoMgt();
    	ManejadorSistema ms = ManejadorSistema.getInstance();
		jmgt.listarJuegos();
		if (cat.equals("Todas")){
			return jmgt.listarJuegos();
		} 
		else {
			List<String> juegosCat = new ArrayList<String>();
			for (String s: jmgt.listarJuegos())
			{
				if (ms.findJuego(s).getCategorias().contains(cat)){
					juegosCat.add(s);
				}
			}
			return juegosCat;
		}
    }

	@Override
	public void remove(String nick) {
		if (this.logueados!= null)
		{
			for (int i = 0; i < logueados.size(); i++) {
				if (logueados.get(i).getNick().equals(nick)){
					logueados.remove(i);
					return;
				}
			}			
		}
		
	}
	
	public JuegoVO buscarJuego(String nombre){
			Juego juego = ManejadorSistema.getInstance().findJuego(nombre);
			if(juego!=null){
			JuegoVO jvo = juego.getJuegoVO();
			return jvo;
			}
			else return null;
	} 
	
	public ClienteVO buscarCliente(String nombre){
		Cliente us = (Cliente) ManejadorSistema.getInstance().findUsuarioPorNick(nombre);
		if(us!=null){
			ClienteVO cvo = us.toClienteVO();
			List<JuegoVO> ljvo = new ArrayList<JuegoVO>();
			List<Juego> lj = us.getJuegosAdquiridos();
			for(Juego j: lj){
				JuegoVO jvo = j.getJuegoVO();
				ljvo.add(jvo);
			}
			cvo.setJuegosAdquiridos(ljvo);
			return cvo;
		}
		else return null;
} 
	
	public String getLinkJuego(String nom){
		JuegoMgt jmgt = SystemFactory.getInstance().getJuegoMgt();
		return jmgt.getLinkJuego(nom);
	}
	
	public List<JuegoVO> listarJuegosVisitante(String cat, int pag){
		List<JuegoVO> res = new ArrayList<JuegoVO>();
		if(cat.equals("Todas"))
			res = SystemFactory.getInstance().getJuegoMgt().listarJuegosVO();
		else
			for(JuegoVO jvo : SystemFactory.getInstance().getJuegoMgt().listarJuegosVO()){
				if(jvo.getCategorias().contains(cat))
					res.add(jvo);
			}
		return res;
	}
	
	public List<JuegoVO> listarJuegosDesarrollador(String cat, int pag, String nick, boolean isAprov){
		List<JuegoVO> res = new ArrayList<JuegoVO>();
		Desarrollador des = (Desarrollador) ManejadorSistema.getInstance().findUsuarioPorNick(nick);
		if(des != null){
			if(isAprov){
				for(JuegoVO jue : des.toDesarrolladorVO().getJuegosPublicados()){
					if(jue.getUltAprobada() != null)
						if(cat.equals("Todas") || jue.getCategorias().contains(cat))
							res.add(jue);
				}
			}
			else{
				for(JuegoVO jue : des.toDesarrolladorVO().getJuegosPublicados()){
					if(cat.equals("Todas") || jue.getCategorias().contains(cat))
						res.add(jue);
				}
			}
		}
		return res;
	}
	
	public List<JuegoVO> listarJuegosCliente(String cat, int pag, String nick){
		List<JuegoVO> res = new ArrayList<JuegoVO>();
		Cliente cli = (Cliente) ManejadorSistema.getInstance().findUsuarioPorNick(nick);
		if(cli != null){
			for(JuegoVO jue : cli.toClienteVO().getJuegosAdquiridos()){
				if(cat.equals("Todas") || jue.getCategorias().contains(cat))
					res.add(jue);
			}
		}
		return res;
	}
	
	public List<String> obtenerCategorias(){
		List<String> res = ManejadorSistema.getInstance().obtenerCategorias();
		res.add(0, "Todas");
		return res;
	}
	
}
